package com.nuoniu.sibanyun.service.erp.in.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nuoniu.sibanyun.common.exception.NuoNiuException;
import com.nuoniu.sibanyun.common.lang.StringUtils;
import com.nuoniu.sibanyun.entity.dto.ExistQuantityDto;
import com.nuoniu.sibanyun.entity.dto.InInventoryInfoDto;
import com.nuoniu.sibanyun.entity.dto.InInventoryInfoSearchDto;
import com.nuoniu.sibanyun.entity.dto.statistics.InventoryStorageOnHandDto;
import com.nuoniu.sibanyun.entity.dto.statistics.StorageOnHandDto;
import com.nuoniu.sibanyun.entity.erp.in.InInventoryInfo;
import com.nuoniu.sibanyun.entity.erp.in.InWarehouse;
import com.nuoniu.sibanyun.entity.inOut.VInOutRecordDetail;
import com.nuoniu.sibanyun.entity.production.ErpMrpProgramme;
import com.nuoniu.sibanyun.entity.vo.InInventoryCheckSearchVo;
import com.nuoniu.sibanyun.entity.vo.statistics.InventoryStorageOnHandVo;
import com.nuoniu.sibanyun.entity.vo.statistics.StorageOnHandVo;
import com.nuoniu.sibanyun.mapper.erp.in.InInventoryInfoMapper;
import com.nuoniu.sibanyun.service.erp.IErpAccountService;
import com.nuoniu.sibanyun.service.erp.in.IInInventoryInfoService;
import com.nuoniu.sibanyun.userThread.UserInfo;
import com.nuoniu.sibanyun.userThread.UserThreadLocal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 物料信息 服务实现类
 * </p>
 *
 * @author 小啊刚
 * @since 2020-12-28
 */
@Service
public class InInventoryInfoServiceImpl extends ServiceImpl<InInventoryInfoMapper, InInventoryInfo> implements IInInventoryInfoService {

    @Autowired
    private IErpAccountService erpAccountService;
    @Override
    public InInventoryInfo getByInventory(VInOutRecordDetail inOutRecordDetail) {
        Integer inventoryLocationId = inOutRecordDetail.getInventoryLocationId();
        UserInfo userInfo = UserThreadLocal.get();
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("company_id",userInfo.getCompanyId());
        queryWrapper.eq("inventory_id",inOutRecordDetail.getInventoryId());
        queryWrapper.eq("warehouse_id",inOutRecordDetail.getWarehouseId());
        queryWrapper.last("LIMIT 1");
        if(null != inventoryLocationId){
            queryWrapper.eq("inventory_location_id",inventoryLocationId);
            queryWrapper.last("LIMIT 1");
        }
        InInventoryInfo one = this.getOne(queryWrapper);
        return one;
    }

    @Override
    public Page<InInventoryInfo> pageList(Page page, InInventoryInfoDto inInventoryInfoDto) {
        UserInfo userInfo = UserThreadLocal.get();
        QueryWrapper<InInventoryInfo> queryWrapper = new QueryWrapper();
        queryWrapper.eq("company_id",userInfo.getCompanyId());
        if(null != inInventoryInfoDto.getWarehouseId()){
            queryWrapper.eq("warehouse_id",inInventoryInfoDto.getWarehouseId());
        }
        if(null != inInventoryInfoDto.getInventoryId()){
            queryWrapper.eq("inventory_id",inInventoryInfoDto.getInventoryId());
        }
        String keyWord = inInventoryInfoDto.getInventoryKeyWord();
        if(StringUtils.isNotBlank(keyWord)){
            queryWrapper.eq("inventory_code",keyWord).or().eq("inventory_name",keyWord);
        }
        page(page, queryWrapper);
        return page;
    }

    @Override
    public Page<InInventoryCheckSearchVo> pageInInventoryCheckSearchVo(Page page, InInventoryInfoSearchDto inInventoryInfoSearchDto) {
        UserInfo userInfo = UserThreadLocal.get();
        Page<InInventoryCheckSearchVo> inInventoryCheckSearchVoPage = baseMapper.pageInInventoryCheckSearchVo(page, userInfo.getCompanyId(), inInventoryInfoSearchDto);
        return inInventoryCheckSearchVoPage;
    }

    @Override
    public InInventoryCheckSearchVo inInventoryCheckSearchVo(Long warehouseId, String inventoryCode) {
        if (null == warehouseId)throw new NuoNiuException("请选择仓库");
        if (StringUtils.isBlank(inventoryCode))throw new NuoNiuException("请选择物料");
        UserInfo userInfo = UserThreadLocal.get();
        InInventoryCheckSearchVo inInventoryCheckSearchVo = baseMapper.inInventoryCheckSearchVo(userInfo.getCompanyId(), warehouseId, inventoryCode);
        return inInventoryCheckSearchVo;
    }

    @Override
    public HashMap<String, Object> getExistingQuantityReport() {
        return null;
    }

    @Override
    public Double getInventoryCount(Integer inventoryId, ErpMrpProgramme mrpProgramme) {
        UserInfo userInfo = UserThreadLocal.get();
        if(mrpProgramme.getIsSystem() != null && mrpProgramme.getIsSystem().equals(1)) {
            return baseMapper.getInventoryCount(inventoryId, userInfo.getCompanyId());
        }
        return baseMapper.getInventoryCountByWarehouse(inventoryId, mrpProgramme.getWarehouseIds(), userInfo.getCompanyId());
    }

    @Override
    public BigDecimal getExistQuantity(Integer inventoryId) {
        UserInfo userInfo = UserThreadLocal.get();
        Integer currentAccountId = erpAccountService.getCurrentAccountId();
        BigDecimal existQuantity = baseMapper.getExistQuantity(userInfo.getCompanyId(), currentAccountId, inventoryId);
        return existQuantity;
    }

    @Override
    public  HashMap<Integer, BigDecimal> getExistQuantityByWarehouseId(ExistQuantityDto existQuantityDto) {
        HashMap<Integer, BigDecimal> resultMap = new HashMap<>();
        List<Integer> inventoryIds = existQuantityDto.getInventoryIds();
        Integer warehouseId = existQuantityDto.getWarehouseId();
        if( null == inventoryIds || inventoryIds.size() ==0 )throw new NuoNiuException("请选择物料");
        UserInfo userInfo = UserThreadLocal.get();
        Integer currentAccountId = erpAccountService.getCurrentAccountId();
        if(null == warehouseId){
            List<HashMap<String,Object>> map = baseMapper.listExistQuantity(userInfo.getCompanyId(), currentAccountId, inventoryIds);
            map.forEach(m-> resultMap.put(Integer.valueOf(m.get("inventoryId").toString()),new BigDecimal(m.get("inventoryQuantity").toString())));
        }else {
            List<HashMap<String,Object>> map = baseMapper.listExistQuantityByWarehouseId(userInfo.getCompanyId(), currentAccountId, inventoryIds, warehouseId);
            map.forEach(m-> resultMap.put(Integer.valueOf(m.get("inventoryId").toString()),new BigDecimal(m.get("inventoryQuantity").toString())));
        }
        return resultMap;
    }

    @Override
    public Page<StorageOnHandVo> statisticStorageOnHandVo(Page page,StorageOnHandDto storageOnHandDto) {
        UserInfo userInfo = UserThreadLocal.get();
        Integer currentAccountId = erpAccountService.getCurrentAccountId();
        Page<StorageOnHandVo> storageOnHandVoPage = baseMapper.statisticStorageOnHandDetailVo(page, userInfo.getCompanyId(), currentAccountId, storageOnHandDto);
        List<StorageOnHandVo> records = storageOnHandVoPage.getRecords();
        if(records.size() > 0){
            Set<Integer> inventorySet = records.stream().map(StorageOnHandVo::getInventoryId).collect(Collectors.toSet());
            String inventoryIds = StringUtils.join(inventorySet,",");
            List<StorageOnHandVo> storageOnHandVos = baseMapper.statisticStorageOnHandVo(inventoryIds, storageOnHandDto);
            if(null != storageOnHandVos && storageOnHandVos.size() > 0){
                records.addAll(storageOnHandVos);
            }
        }
        return storageOnHandVoPage;
    }

    @Override
    public List<InventoryStorageOnHandVo> statisticInventoryStorageOnHandVo(InventoryStorageOnHandDto inventoryStorageOnHandDto) {
        UserInfo userInfo = UserThreadLocal.get();
        Integer currentAccountId = erpAccountService.getCurrentAccountId();
        List<InventoryStorageOnHandVo> inventoryStorageOnHandVos = baseMapper.statisticInventoryStorageOnHandVo(userInfo.getCompanyId(), currentAccountId, inventoryStorageOnHandDto);
        return inventoryStorageOnHandVos;
    }

    @Override
    public void updateFromInWarehouse(InWarehouse inWarehouse) {
        Long warehouseId = inWarehouse.getId();
        String whName = inWarehouse.getWhName();
        UpdateWrapper<InInventoryInfo> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("warehouse_name",whName);
        updateWrapper.eq("company_id",inWarehouse.getCompanyId());
        updateWrapper.eq("warehouse_id",warehouseId);
        update(updateWrapper);

    }

    @Override
    public Double getInventorySum(Integer inventoryId, Integer companyId) {
        return baseMapper.getInventoryCount(inventoryId, companyId);
    }


}
